home *** CD-ROM | disk | FTP | other *** search
Wrap
/* SimpleInMovies Sample programs demonstrating how to open and display QuickTime™ Movies. SimpleInController.c file contains the code for the routines having to do with the standard movie controller. Each window is associated with a movie and an instance of the movie controller. There are menu equivalents for movie controller commands to show how to interact with the controller. Guillermo A. Ortiz Macintosh Developer Technical Support 07/23/91 Moved the code here and added editing stuff 08/07/91 Added code to put cuts into the scrap when being switched in/out. 08/22/91 Changed FixMovieWindow to accomodate changes in standard controler box. 11/17/91 Fix final interface problems, clean comments. FROM Beta README: GONE: The following mcActions have been removed: mcStop, mcPlayBackwards, mcSetRate, mcIncreaseRate, mcDecreaseRate use mcPlay instead mcStepForward, mcStepBackward use mcStep instead mcToggleLooping use mcGetLooping and mcSetLooping mcIncreaseVolume, mcDecreaseVolume use mcGetVolume and mcSetVolume mcSetSelectionBegin, mcSetSelectionEnd changed to mcSetSelectionBegin and mcSetSelectionDuration, with the behaviour that mcSetSelectionBegin does nothing, just saves the time passed, and mcSetSelectionDuration then applies the beginning and the duration to the movie. Also, the duration can be negative. */ #include <SimpleInMovie.h> Movie cuts; /* local scrappy movie */ void ChangeMooVState(void); void ChangeMooVSound(void); void NextMooVFrame(void); void PrevMooVFrame(void); void SetMovieLoop(short); void DoEnableEditing(void); void DoUndoMovie(void); void DoCutMovie(void); void DoCopyMovie(void); void DoPasteMovie(void); void DoClearMovie(void); void DoSelectAll(void); extern void DoScrapStuff(Boolean toScrap); OSErr FixMovieWindow(WindowPtr window); Boolean IsPlayerEvent(WindowPtr, EventRecord *); extern Boolean IsAppWindow(WindowPtr); /******************************************************************************************* *******************************************************************************************/ /* the following rutines service menu commands that have to do with the movie being played; we call the controller to affect the action because this allows the controller to be in sync with the movie. If you change the state of the movie through Movie Toolbox routines you have to call MCMovieChanged in order to allow the controller to get back in sync. */ /* stops or starts the movie */ void ChangeMooVState() { WindowPtr window; DocRecHandle wHndl; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( GetMovieRate((*wHndl)->wMovie) ) {/* the movie is playing call controller to stop it */ MCDoAction((*wHndl)->wPlayer, mcActionPlay, 0x0000000); /* rate=zero to stop */ } else { /* needs to start movie */ MCDoAction((*wHndl)->wPlayer, mcActionPlay, (Ptr)0x00010000); /* rate=one to play */ } } } } /* sets sound on or off */ void ChangeMooVSound() { WindowPtr window; DocRecHandle wHndl; short vol; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { MCDoAction((*wHndl)->wPlayer , mcActionGetVolume, &vol); /* get current volume */ if (vol) { (*wHndl)->soundVolume = vol; vol = 0; MCDoAction((*wHndl)->wPlayer , mcActionSetVolume, (Ptr)vol); /* and set it */ } else { vol = (*wHndl)->soundVolume; MCDoAction((*wHndl)->wPlayer , mcActionSetVolume, (Ptr)vol); /* and set it */ } } } } /* advances one frame */ void NextMooVFrame() { short step = 1; /* advance one frame */ WindowPtr window; DocRecHandle wHndl; ComponentResult err; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( err = MCDoAction((*wHndl)->wPlayer, mcActionStep, (Ptr)step) ) DebugStr("\pError at step forward"); } } } /* goes to previous frame */ void PrevMooVFrame() { short step = -1; /* Negative values go backwards */ WindowPtr window; DocRecHandle wHndl; ComponentResult err; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( err = MCDoAction((*wHndl)->wPlayer, mcActionStep, (Ptr)step) ) DebugStr("\pError at step backward"); } } } /* Handle changes to loop settings and also turns palindrome on or off */ void SetMovieLoop(whatAction) short whatAction; { WindowPtr window; DocRecHandle wHndl; Boolean isLooping; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { switch (whatAction) { case loopMovie: MCDoAction((*wHndl)->wPlayer, mcActionGetLooping, (void *)&isLooping); MCDoAction((*wHndl)->wPlayer, mcActionSetLooping, (void *)!isLooping); break; case weirdLoopMovie: MCDoAction((*wHndl)->wPlayer, mcActionGetLoopIsPalindrome, (void *)&isLooping); MCDoAction((*wHndl)->wPlayer, mcActionSetLoopIsPalindrome, (void *)!isLooping); break; } } } } /******************************************************************************************* *******************************************************************************************/ /* the idea in this function is to check if the event being handled belongs to one instance of the controller; even when it is not a controller event we want to call the component to let it handle idle events. If the controller decides that it has one event it needs to handle and returns true the function returns true; in other cases the function returns false and lets the normal event loop to fall through */ Boolean IsPlayerEvent(window, myEvent) WindowPtr window; EventRecord *myEvent; { #pragma unused (window) DocRecHandle wHndl; WindowPtr wind; Boolean result = false; /* loop for each window until event has been taken care of or there are no more windows */ for (wind = *(WindowPtr *)WindowList;wind;wind = (WindowPtr)((WindowPeek)wind)->nextWindow) { /* there may not be a window */ if (wHndl = (DocRecHandle)GetWRefCon(wind)) { /* Get the storage handle */ result |= (MCIsPlayerEvent((*wHndl)->wPlayer, myEvent)); /* return true if controller event is handled */ } } return result; } /******************************************************************************************* *******************************************************************************************/ /* Routines to handle editing commands */ /* Functions toggles editing on/off */ void DoEnableEditing(void) { WindowPtr window; DocRecHandle wHndl; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { MCEnableEditing((*wHndl)->wPlayer,!MCIsEditingEnabled((*wHndl)->wPlayer)); } } } /* Undos edits */ void DoUndoMovie(void) { WindowPtr window; DocRecHandle wHndl; ComponentResult err; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( MCIsEditingEnabled((*wHndl)->wPlayer)) { if ( ! MCIsControllerAttached((*wHndl)->wPlayer) ) /* if needed, atach it before */ MCSetControllerAttached((*wHndl)->wPlayer, true); /* performing operation */ /* depending on what is being undo, this operation could leave an empty box movie, since the controller is still attached it would jump to the top of the window; later on the update that follows the controller goes away but it looks kind of ugly so we make it invisible here, after repositioning the controller FixMovieWindow will turn it on again. */ MCSetVisible((*wHndl)->wPlayer, false); if ( err = MCUndo((*wHndl)->wPlayer) ) DebugStr("\pError at MCUndo"); else if (FixMovieWindow(window)) /* movie size may have changed, check it up */ DebugStr("\pSomething wrong at FixMovieWindow"); } } } } void DoCutMovie(void) { WindowPtr window; DocRecHandle wHndl; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( MCIsEditingEnabled((*wHndl)->wPlayer)) { if ( ! MCIsControllerAttached((*wHndl)->wPlayer) ) /* if needed, atach it before */ MCSetControllerAttached((*wHndl)->wPlayer, true); /* performing operation */ if (cuts) DisposeMovie(cuts); /* get rid of movie first */ /* Cut can result in an empty box movie; therefore make controller invisible and then let FixMovieWindow turn it on when all the repositioning is done. */ MCSetVisible((*wHndl)->wPlayer, false); if ( !(cuts = MCCut((*wHndl)->wPlayer)) ) { DebugStr("\pError at MCCut"); } if (FixMovieWindow(window)) /* movie size may have changed, check it up */ DebugStr("\pSomething wrong at FixMovieWindow"); } } } } void DoCopyMovie(void) { WindowPtr window; DocRecHandle wHndl; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( MCIsEditingEnabled((*wHndl)->wPlayer)) { if (cuts) DisposeMovie(cuts); /* get rid of movie first */ if ( !(cuts = MCCopy((*wHndl)->wPlayer)) ) { DebugStr("\pError at MCCopy"); /* nothing selected maybe*/ } } } } } /* Pastes movie pieces into front most window if editing is enabled. But first it check if the movie has its controller attached, if not (the movie has no spatial bounds, empty or no video movie, then the controller is attached. The call to FisMovieWindow would detach the controller if the movie still has no bounds. */ void DoPasteMovie(void) { WindowPtr window; DocRecHandle wHndl; ComponentResult err; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (cuts && IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( MCIsEditingEnabled((*wHndl)->wPlayer)) { if ( ! MCIsControllerAttached((*wHndl)->wPlayer) ) /* if needed */ MCSetControllerAttached((*wHndl)->wPlayer, true); /* atach it */ /* paste can result in an empty box movie; therefore make controller invisible and then let FixMovieWindow turn it on when all the repositioning is done. */ MCSetVisible((*wHndl)->wPlayer, false); if ( err = MCPaste((*wHndl)->wPlayer, cuts) ) { DebugStr("\pError at MCPaste"); } else if (FixMovieWindow(window)) DebugStr("\pSomething wrong at FixMovieWindow"); } } } } void DoClearMovie(void) { WindowPtr window; DocRecHandle wHndl; ComponentResult err; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( MCIsEditingEnabled((*wHndl)->wPlayer)) { if ( ! MCIsControllerAttached((*wHndl)->wPlayer) ) /* if needed */ MCSetControllerAttached((*wHndl)->wPlayer, true); /* atach it */ /* Clear can result in an empty box movie; therefore make controller invisible and then let FixMovieWindow turn it on when all the repositioning is done. */ MCSetVisible((*wHndl)->wPlayer, false); if ( err = MCClear((*wHndl)->wPlayer) ) { DebugStr("\pError at MCClear"); } if (FixMovieWindow(window)) /* movie size may have changed, check it up */ DebugStr("\pSomething wrong at FixMovieWindow"); } } } } /* selects the whole movie for editing */ void DoSelectAll(void) { WindowPtr window; DocRecHandle wHndl; ComponentResult err; TimeRecord tRec; if (window = FrontWindow()) { /* don't bother if no movies to play */ if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) { if ( MCIsEditingEnabled((*wHndl)->wPlayer)) { tRec.value.lo = tRec.value.hi = 0; tRec.base = 0; tRec.scale = GetMovieTimeScale((*wHndl)->wMovie); if ( err = MCDoAction((*wHndl)->wPlayer, mcActionSetSelectionBegin, &tRec)) { DebugStr("\pError trying mcActionSetSelectionBegin"); } tRec.value.hi = 0; tRec.value.lo = GetMovieDuration((*wHndl)->wMovie); tRec.base = 0; tRec.scale = GetMovieTimeScale((*wHndl)->wMovie); if ( err = MCDoAction((*wHndl)->wPlayer, mcActionSetSelectionDuration, &tRec)) { DebugStr("\pError trying mcActionSetSelectionDuration"); } } } } } /******************************************************************************************* *******************************************************************************************/ /* Utility proc that fixes the size of the display window when the dimensions have changed; it expects all the checks done when called. */ OSErr FixMovieWindow(WindowPtr window) WindowPtr window; { DocRecHandle wHndl; Rect moovBox, controllerBox; OSErr err = noErr; if (wHndl = (DocRecHandle)GetWRefCon(window)) { GetMovieBox((*wHndl)->wMovie,&moovBox); /* Use the movie box to resize window */ if ( ! EmptyRect(&moovBox)) { /* usual case when movie has video to show */ if (err = MCGetControllerBoundsRect((*wHndl)->wPlayer, &controllerBox) ) DebugStr("\pError at MCGetControllerBoundsRect"); UnionRect(&moovBox, &controllerBox, &moovBox); SizeWindow(window, moovBox.right-moovBox.left,moovBox.bottom-moovBox.top,true); } else { /* new movie or a movie that lost all visible portions through editing */ /* positioning the controller while it is attached is not possible so we detach it in order to avoid the controller jumping to the top of the window when the movie has not visible stuff. */ if ( MCIsControllerAttached((*wHndl)->wPlayer) ) MCSetControllerAttached((*wHndl)->wPlayer, false); /* detach it */ if (err = MCGetControllerBoundsRect((*wHndl)->wPlayer, &controllerBox) ) DebugStr("\pError at MCGetControllerBoundsRect"); controllerBox.top = ((GrafPtr) window)->portRect.bottom - controllerBox.bottom; controllerBox.right = ((GrafPtr) window)->portRect.right; controllerBox.bottom = ((GrafPtr) window)->portRect.bottom; MCPositionController((*wHndl)->wPlayer, &moovBox, &controllerBox, mcTopLeftMovie /*controllerCreationFlags*/); } } if ( ! MCGetVisible((*wHndl)->wPlayer) ) { if ( err = MCSetVisible((*wHndl)->wPlayer, true) ) DebugStr("\pError at MCSetVisible"); } return err; } /******************************************************************************************* *******************************************************************************************/ /* This procedure gets called with suspend and resume events to put a movie into the scrap when being switched back and to get the scrap when comming to the front. */ extern void DoScrapStuff(toScrap) Boolean toScrap; { OSErr err; if (toScrap) /* check if we have a movie to */ if (cuts) /* put in the scrap */ if ( err = PutMovieOnScrap(cuts, 0L) ) /* now put it there */ DebugStr("\pSomething wrong trying to put movie to scrap"); else { /* convert scrap to local */ if (cuts) DisposeMovie(cuts); /* get rid of movie first */ if ( !(cuts = NewMovieFromScrap(0) ) ) DebugStr("\pSomething wrong trying to get movie from scrap"); } } /******************************************************************************************* *******************************************************************************************/